package com.jdd.modules.parkmonthly.service.impl;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import javax.annotation.Resource;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.jdd.modules.parkcar.mapper.ParkCarMonthlyMapper;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.jdd.common.api.vo.Result;
import com.jdd.common.constant.JddConstant;
import com.jdd.common.system.vo.LoginUser;
import com.jdd.common.util.DateUtil;
import com.jdd.common.util.LoginUserUtils;
import com.jdd.common.util.SnowFlakeUtil;
import com.jdd.modules.configcartype.entity.ConfigCarType;
import com.jdd.modules.configcartype.service.IConfigCarTypeService;
import com.jdd.modules.parkcar.entity.ParkCarMonthly;
import com.jdd.modules.parkcar.entity.ParkSpace;
import com.jdd.modules.parkcar.service.IParkCarMonthlyService;
import com.jdd.modules.parkcar.service.IParkSpaceService;
import com.jdd.modules.parking.entity.ConfigParkInfo;
import com.jdd.modules.parking.entity.ParkCarEnterLog;
import com.jdd.modules.parking.entity.ParkInfo;
import com.jdd.modules.parking.service.IParkInfoService;
import com.jdd.modules.parking.service.IparkCarEnterLogService;
import com.jdd.modules.parkmonthly.dto.MonthlyCarDto;
import com.jdd.modules.parkmonthly.dto.MonthlyCardDelayDto;
import com.jdd.modules.parkmonthly.dto.TurnCardVo;
import com.jdd.modules.parkmonthly.entity.MonthlyCarConfig;
import com.jdd.modules.parkmonthly.entity.MonthlyCarTypeConvert;
import com.jdd.modules.parkmonthly.entity.MonthlyCardEditInfo;
import com.jdd.modules.parkmonthly.entity.MonthlyCardInfo;
import com.jdd.modules.parkmonthly.entity.MonthlyPackageInfo;
import com.jdd.modules.parkmonthly.entity.PermissionArea;
import com.jdd.modules.parkmonthly.mapper.MonthlyCardInfoMapper;
import com.jdd.modules.parkmonthly.mapper.MonthlyDepartmentMapper;
import com.jdd.modules.parkmonthly.service.IMonthlyCarTypeConvertService;
import com.jdd.modules.parkmonthly.service.IMonthlyCardEditInfoService;
import com.jdd.modules.parkmonthly.service.IMonthlyCardInfoService;
import com.jdd.modules.parkmonthly.service.IMonthlyPackageInfoService;
import com.jdd.modules.parkmonthly.service.IPermissionAreaService;
import com.jdd.modules.parkmonthly.vo.AddMonthlyCardInfoVO;
import com.jdd.modules.sdkidentifyresultpushlog.entity.vo.MonthlyCardAndPackageVo;
import com.jdd.modules.sdkidentifyresultpushlog.entity.vo.ParkCarEnterLogSyncV3Vo;
import com.jdd.modules.sdkidentifyresultpushlog.service.ISdkIdentifyResultPushLogV3Service;

import cn.hutool.core.collection.CollectionUtil;
import lombok.extern.slf4j.Slf4j;


/**
 * @Description: 月卡信息表
 * @Author: jdd
 * @Date: 2021-11-09
 * @Version: V1.0
 */
@Service
@Slf4j
@Lazy
public class MonthlyCardInfoServiceImpl extends ServiceImpl<MonthlyCardInfoMapper, MonthlyCardInfo> implements IMonthlyCardInfoService {

    @Resource
    private IMonthlyCarTypeConvertService iMonthlyCarTypeConvertService;
    @Resource
    private IMonthlyPackageInfoService iMonthlyPackageInfoService;
    @Resource
    private IMonthlyCardEditInfoService iMonthlyCardEditInfoService;
    @Resource
    private IparkCarEnterLogService iparkCarEnterLogService;
    @Resource
    private IPermissionAreaService iPermissionAreaService;
    @Resource
    private IParkCarMonthlyService iParkCarMonthlyService;
    @Resource
    private ParkCarMonthlyMapper parkCarMonthlyMapper;
    @Resource
    private IParkSpaceService parkSpaceService;
    @Resource
    private MonthlyCardInfoMapper monthlyCardInfoMapper;
    @Resource
    private IMonthlyCarTypeConvertService monthlyCarTypeConvertService;
    @Resource
    private MonthlyDepartmentMapper monthlyDepartmentMapper;
    @Autowired
    private IConfigCarTypeService configCarTypeService;

    @Autowired
    private IParkInfoService parkInfoService;
    @Autowired
    @Lazy
    private ISdkIdentifyResultPushLogV3Service sdkIdentifyResultPushLogV3Service;



    @Override
    public List<String> getIds(QueryWrapper<MonthlyCardInfo> queryWrapper) {
        return monthlyCardInfoMapper.getIds(queryWrapper);
    }

    /**
     * 开通延期注销-确认提示
     *
     * @param monthlyCarDto
     * @param monthlyCarDto
     * @return
     */
    @Override
    public Result<String> delayConfirm(MonthlyCarDto monthlyCarDto) {
        Result<String> result = new Result<>();
        if (CollectionUtils.isEmpty(monthlyCarDto.getPlateNoList())) {
            result.setSuccess(true);
            result.setResult("");
            return result;
        }
        //查询操作车辆是否在场内
        List<String> plateNoList = this.queryCarIsInPark(monthlyCarDto);
        String plateNos = String.join(",", plateNoList);
        //查询是否立即生效
        LambdaQueryWrapper<MonthlyCarConfig> monthlyCarConfigLambdaQueryWrapper = new LambdaQueryWrapper<>();
        monthlyCarConfigLambdaQueryWrapper.eq(MonthlyCarConfig::getParkCode, monthlyCarDto.getParkCode());
        if (CollectionUtil.isNotEmpty(plateNoList)) {
            result.setSuccess(true);
            result.setMessage("车牌号列表中存在场内车辆");
            result.setResult(plateNos);
            return result;
        } else {
            result.setSuccess(true);
            result.setResult(plateNos);
            return result;
        }
    }

    /**
     * 月卡新增
     *
     * @param monthlyCardInfo
     * @return
     */
    @Override
    public Result<MonthlyCardInfo> add(MonthlyCardInfo monthlyCardInfo) {

        log.info("新增月卡信息，传入的参数------------------------》:{}", monthlyCardInfo);
        // 查询企业信息
        ParkInfo parkInfo = parkInfoService.getParkInfo();
        monthlyCardInfo.setParkCode(parkInfo.getParkCode());
        monthlyCardInfo.setParkName(parkInfo.getParkName());
        // 获取车位车牌，车位
        List<String> plateNoList = monthlyCardInfo.getPlateNoList();
        List<String> spaces = monthlyCardInfo.getParkNumberList();
        boolean addMonthly = true;
        // 1.新增月卡
        addMonthly = getMonthlyCardInfo(monthlyCardInfo);
        if (!addMonthly) {
            return Result.error("新增月卡信息失败！");
        }

        // 2.获取车位信息，更新车位，不更新费用
        List<ParkSpace> parkSpaces = new ArrayList<>();
        for (String paces : spaces) {
            ParkSpace parkSpace = parkSpaceService.getById(paces);
            parkSpace.setMonthlyCode(monthlyCardInfo.getMonthlyCode());
            parkSpace.setMonthlyCardId(monthlyCardInfo.getId());
            parkSpace.setUserName(monthlyCardInfo.getCarOwnerName());
            parkSpace.setMobile(monthlyCardInfo.getTelephone());
            parkSpace.setStartTime(monthlyCardInfo.getBeginTime());
            parkSpace.setEndTime(monthlyCardInfo.getEndTime());
            parkSpace.setAddress(monthlyCardInfo.getAddress());
            parkSpace.setStatus("Y");
            parkSpace.setCreateUser(monthlyCardInfo.getCreateUserName());
            parkSpaces.add(parkSpace);
        }
        addMonthly = parkSpaceService.updateBatchById(parkSpaces);
        //车位上传
         if (!addMonthly) {
            return Result.error("新增车信息失败！");
        }
        log.info("新增月卡绑定的车位信息为------------------------>:{}", parkSpaces);
        // 3.新增月卡操作记录
        addMonthly = getMonthlyCardEditInfo(monthlyCardInfo, JddConstant.StringNumber.STRING_FOUR);
        if (!addMonthly) {
            return Result.error("新增月卡操作记录信息失败！");
        }

        Result result = dealInParkCar(parkSpaces, plateNoList, monthlyCardInfo);

        return  result;

    }


    /**
     * 处理在场车辆信息
     *
     * @param parkSpaces
     * @param plateNoList
     * @param monthlyCardInfo
     * @return
     */
    private Result dealInParkCar(List<ParkSpace> parkSpaces, List<String> plateNoList, MonthlyCardInfo monthlyCardInfo) {
        // 新增月租车信息
        List<ParkCarMonthly> list = getParkCarMonthlyEntity(parkSpaces, plateNoList, monthlyCardInfo);
        boolean addResult = iParkCarMonthlyService.saveBatch(list);
         if (!addResult) {
            log.error("新增月租车信息失败！");
            return Result.error("新增月租车信息失败！");
        }
        if (monthlyCardInfo.getEndTime().equals(monthlyCardInfo.getBeginTime())) {
            log.info("月卡未开通具体时间！");
            return Result.ok("开通成功！");
        }
        LambdaQueryWrapper<MonthlyCarConfig> monthlyCarConfigLambdaQueryWrapper = new LambdaQueryWrapper<>();
        monthlyCarConfigLambdaQueryWrapper.eq(MonthlyCarConfig::getParkCode, monthlyCardInfo.getParkCode());
        List<String> areaList = parkSpaces.stream().map(ParkSpace::getAreaId).distinct().collect(Collectors.toList());

        // 办卡时，查询勾选车位在场车辆信息(最近一条记录，且在指定的区域)
        List<ParkCarEnterLog> parkCarEnterLogs = getList(monthlyCardInfo.getParkCode(),plateNoList,areaList);
        log.info(" 办卡时，查询勾选车位在场车辆信息==================>:{}", parkCarEnterLogs);
        if (CollectionUtils.isEmpty(parkCarEnterLogs)) {

            return Result.ok("开通成功");
        }
        // 下次生效，不转卡
        if (JddConstant.IntNumber.INT_TWO == monthlyCardInfo.getIsEffect()) {
            return Result.ok("开通成功");
        }
        QueryWrapper<ParkSpace> parkSpaceQueryWrapper = new QueryWrapper<>();
        parkSpaceQueryWrapper.eq("park_code", monthlyCardInfo.getParkCode());
        parkSpaceQueryWrapper.eq("monthly_card_id", monthlyCardInfo.getId());
        parkSpaceQueryWrapper.eq("park_status", 0);
        List<ParkSpace> spaces = parkSpaceService.list(parkSpaceQueryWrapper);
        return addParkCarEnterInfo(monthlyCardInfo, spaces, parkCarEnterLogs);
    }

    /**
     * 未绑定车位查询
     *
     * @param monthlyCardInfo
     * @return
     */
    @Override
    public Result<List<ParkSpace>> queryUnUseSpace(MonthlyCardInfo monthlyCardInfo) {
        log.info("查询未绑定的车位信息，传入的参数------------------------》：{}", monthlyCardInfo);
        Result<List<ParkSpace>> result = new Result<>();

        QueryWrapper<ParkCarMonthly> parkCarMonthlyQueryWrapper = new QueryWrapper<>();
        parkCarMonthlyQueryWrapper.eq("park_code", monthlyCardInfo.getParkCode());
        parkCarMonthlyQueryWrapper.eq("status", "Y");
        List<ParkCarMonthly> parkCarMonthlyList = iParkCarMonthlyService.list(parkCarMonthlyQueryWrapper);
        List<String> carNumberList = parkCarMonthlyList.stream().map(ParkCarMonthly::getParkNumber).distinct().collect(Collectors.toList());

        QueryWrapper<ParkSpace> parkSpaceQueryWrapper = new QueryWrapper<>();
        parkSpaceQueryWrapper.eq("park_code", monthlyCardInfo.getParkCode());
        if (CollectionUtils.isNotEmpty(carNumberList)) {
            parkSpaceQueryWrapper.notIn("park_number", carNumberList);
        }
        // 默认权限，选全部区域
        if (StringUtils.isEmpty(monthlyCardInfo.getThroughAuthorityId())) {
            List<ParkSpace> list = parkSpaceService.list(parkSpaceQueryWrapper);
            result.setSuccess(true);
            result.setResult(list);
            return result;
        }
        // 权限不为空
        QueryWrapper<PermissionArea> permissionAreaQueryWrapper = new QueryWrapper<>();
        permissionAreaQueryWrapper.eq("permission_id", monthlyCardInfo.getThroughAuthorityId());
        List<PermissionArea> list = iPermissionAreaService.list(permissionAreaQueryWrapper);
        List<String> areaList = list.stream().map(PermissionArea::getAreaId).collect(Collectors.toList());
        // 绑定区域为空
        if (CollectionUtils.isEmpty(areaList)) {
            result.setSuccess(true);
            result.setResult(new ArrayList<>());
            return result;
        }
        log.info("查询权限下分配的区域信息-----------------------》：{}", JSONObject.toJSONString(areaList));
        parkSpaceQueryWrapper.in("area_id", areaList);
        List<ParkSpace> parkSpaceList = parkSpaceService.list(parkSpaceQueryWrapper);
        log.info("查询权限下的所有未绑定的车位信息-----------------------》：{}", monthlyCardInfo);
        result.setSuccess(true);
        result.setResult(parkSpaceList);
        return result;
    }


    /**
     * 车辆是否在场查询
     *
     * @param monthlyCarDto
     * @return
     */
    private List<String> queryCarIsInPark(MonthlyCarDto monthlyCarDto) {
        log.info("查询勾选的车位是否为场内车辆，传入参数--------------------------》:{}", monthlyCarDto);
        // 是否有在场车辆
        QueryWrapper<ParkCarEnterLog> parkCarEnterLogQueryWrapper = new QueryWrapper<>();
        parkCarEnterLogQueryWrapper.eq("is_out", JddConstant.StringNumber.STRING_ZERO);
        parkCarEnterLogQueryWrapper.eq("park_code", monthlyCarDto.getParkCode());
        if (CollectionUtils.isNotEmpty(monthlyCarDto.getPlateNoList())) {
            parkCarEnterLogQueryWrapper.in("plate_no", monthlyCarDto.getPlateNoList());
        }
        List<ParkCarEnterLog> parkCarEnterLogs = iparkCarEnterLogService.list(parkCarEnterLogQueryWrapper);
        log.info("查询勾选的车位的入场记录，查询结果为--------------------------》:{}", parkCarEnterLogs);
        List<String> plateNoList = parkCarEnterLogs.stream().map(ParkCarEnterLog::getPlateNo).distinct().collect(Collectors.toList());
        log.info("查询绑定月卡的车牌号，在场车辆的车牌号--------------------------》:{}", plateNoList);
        return plateNoList;
    }


    /**
     * 查询该月卡信息绑定的车牌号信息
     *
     * @param monthlyCardInfo
     * @return
     */
    @Override
    public Result<List<ParkCarMonthly>> getUpatePlateNoInfo(MonthlyCardInfo monthlyCardInfo) {
        log.info("查询该月卡信息绑定的车牌号信息，传入参数-------------------------》:{}", monthlyCardInfo);
        Result<List<ParkCarMonthly>> result = new Result<>();
        QueryWrapper<ParkCarMonthly> parkCarMonthlyQueryWrapper = new QueryWrapper<>();
        parkCarMonthlyQueryWrapper.select("DISTINCT(plate_no) AS plateNo");
        parkCarMonthlyQueryWrapper.eq("monthly_card_id", monthlyCardInfo.getId());
        List<ParkCarMonthly> parkCarMonthlyList = iParkCarMonthlyService.list(parkCarMonthlyQueryWrapper);
        log.info("查询该月卡信息绑定的车牌号信息，parkCarMonthlyList-------------------------》:{}", parkCarMonthlyList);
        result.setSuccess(true);
        result.setResult(parkCarMonthlyList);
        return result;
    }


    /**
     * 查询该月卡信息绑定的车位信息
     *
     * @param monthlyCardInfo
     * @return
     */
    @Override
    public Result getUpateCarPlaceInfo(MonthlyCardInfo monthlyCardInfo) {
        log.info("查询该月卡信息绑定的车位信息，传入参数-------------------------》:{}", monthlyCardInfo);
        Result<List<ParkSpace>> result = new Result<>();
        QueryWrapper<ParkSpace> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("monthly_card_id", monthlyCardInfo.getId());
        queryWrapper.eq("status", "Y");
        List<ParkSpace> parkSpaceList = parkSpaceService.list(queryWrapper);
        log.info("查询该月卡信息绑定的车位信息，parkSpaceList-------------------------》:{}", monthlyCardInfo);
        result.setSuccess(true);
        result.setResult(parkSpaceList);
        return result;
    }


    /**
     * 注销月卡信息
     *
     * @param monthlyCardInfo1
     * @return
     */
    @Override
    @CacheEvict(value = {"monthly:cardAndPackage"}, allEntries = true)
    public Result getMonthlyCardConcel(MonthlyCardInfo monthlyCardInfo1) {
        log.info("注销月卡信息，传入参数--------------------------》:{}", monthlyCardInfo1);
        boolean resFlag = true;
        MonthlyCardInfo monthlyCardInfo = this.getById(monthlyCardInfo1.getId());
        monthlyCardInfo.setMonthlyMoney(monthlyCardInfo1.getMonthlyMoney());
        monthlyCardInfo.setRemark(monthlyCardInfo1.getRemark());
        QueryWrapper<MonthlyCarConfig> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("park_code", monthlyCardInfo.getParkCode());
        MonthlyPackageInfo monthlyPackageInfo = iMonthlyPackageInfoService.getById(monthlyCardInfo.getPackageId());
        log.info("注销月卡信息，查询月套餐信息--------------------------》:{}", monthlyPackageInfo);
        // 判断是否有在场车辆
        List<ParkCarEnterLog> parkCarEnterLogs = getPlateNoInPark(monthlyCardInfo.getParkCode(), monthlyCardInfo.getId());
        List<ParkCarEnterLog> parkCarEnterLogList = new ArrayList<>();
        List<MonthlyCarTypeConvert> monthlyCarTypeConverts = new ArrayList<>();
        log.info("查询在场记录信息为ssss--------------------------》:{}", parkCarEnterLogs);
        // 若存在入场记录，则生成一条注销时间的临时记录
        if (parkCarEnterLogs.size() > 0) {
            for (ParkCarEnterLog parkCarEnterLog : parkCarEnterLogs) {
                parkCarEnterLog.setId(SnowFlakeUtil.getId());
                parkCarEnterLog.setCarNature(JddConstant.StringNumber.STRING_ZERO);
                // 判断月租是否过期,过期
                if (monthlyCardInfo.getEndTime().before(new Date())) {
                    // 判断入场是否过期
                    if (DateUtil.fomatDateTime(parkCarEnterLog.getCarEnterTime()).before(monthlyCardInfo.getEndTime())) {
                        parkCarEnterLog.setCarEnterTime(DateUtil.fomatDateTimeStr(monthlyCardInfo.getEndTime()));
                    } else {
                        continue;
                    }
                } else {
                    // 未过期
                    parkCarEnterLog.setCarEnterTime(DateUtil.fomatDateTimeStr(new Date()));
                }
                ConfigCarType configCarType = this.getCarType(parkCarEnterLog.getParkCode(), Integer.valueOf(parkCarEnterLog.getCarTypeNo()));
                if (null != configCarType) {
                    parkCarEnterLog.setCarTypeId(configCarType.getId());
                    parkCarEnterLog.setCarTypeName(configCarType.getCarTypeName());
                }
                parkCarEnterLog.setParkNumber("");
                parkCarEnterLog.setMonthlyCardId("");
                parkCarEnterLog.setCreateTime(new Date());
                //组装转卡记录
                MonthlyCarTypeConvert monthlyCarTypeConvert = getMonthlyCarTypeConvert(monthlyCardInfo, parkCarEnterLog, monthlyPackageInfo);
                monthlyCarTypeConverts.add(monthlyCarTypeConvert);
                parkCarEnterLogList.add(parkCarEnterLog);
            }
            log.info("生成入场记录信息为--------------------------》:{}", parkCarEnterLogs);
            if(parkCarEnterLogList.size()>0){
            	resFlag = iparkCarEnterLogService.saveBatch(parkCarEnterLogList);
            	try {
	            	for(ParkCarEnterLog parkCarEnterLog : parkCarEnterLogList){
	            		ParkCarEnterLogSyncV3Vo entity = new ParkCarEnterLogSyncV3Vo();
						entity.setParkCarEnterLogStr(JSON.toJSONString(parkCarEnterLog));
						entity.setParkStatus(JddConstant.ParkSpace.PARKSTATUS_ZERO);
						String url = "";
						sdkIdentifyResultPushLogV3Service.sendMessageV3(entity,url);
	            	}
            	} catch (Exception e) {
					e.printStackTrace();
					log.info("注销月租新增临时车入场记录上传到云端失败->{}",e);
				}
            }
            if (!resFlag) {
                return Result.error("新增转卡失败！");
            }
            resFlag = iMonthlyCarTypeConvertService.saveBatch(monthlyCarTypeConverts);
            if (!resFlag) {
                return Result.error("新增转卡失败！");
            }
        }
        // 3.注销月卡信息
        monthlyCardInfo.setMonthlyStatus(JddConstant.IntNumber.INT_THREE);
        monthlyCardInfo.setUpdateTime(new Date());
        resFlag = this.updateById(monthlyCardInfo);

        if (!resFlag) {
            return Result.error("更新月卡为注销状态失败！");
        }
        // 4.还原车位绑定
        Result<List<ParkSpace>> result = getUpateCarPlaceInfo(monthlyCardInfo);
        List<ParkSpace> parkSpaceList = result.getResult();
        List<ParkSpace> parkSpaceLists= new LinkedList<>();
        if (parkSpaceList.size() > 0) {
            for (ParkSpace parkSpace : parkSpaceList) {
                parkSpace.setParkStatus(JddConstant.StringNumber.STRING_ZERO);
                parkSpace.setMonthlyCode("");
                parkSpace.setAddress("");
                parkSpace.setUserName("");
                parkSpace.setMobile("");
                parkSpace.setMonthlyCardId("");
                parkSpace.setStartTime(null);
                parkSpace.setEndTime(null);
                parkSpace.setPlateNo("");
                parkSpace.setParkStatus(JddConstant.StringNumber.STRING_ZERO);
                resFlag = parkSpaceService.updateById(parkSpace);
                parkSpaceLists.add(parkSpace);
                if (!resFlag) {
                    return Result.error("更新车位失败！");
                }
            }
        }
        // 5.月租车信息
        QueryWrapper<ParkCarMonthly> wrapper = new QueryWrapper<>();
        wrapper.eq("park_code", monthlyCardInfo.getParkCode());
        wrapper.eq("monthly_card_id", monthlyCardInfo.getId());
        iParkCarMonthlyService.remove(wrapper);
         // 6.新增月卡操作记录
        resFlag = getMonthlyCardEditInfo(monthlyCardInfo, JddConstant.StringNumber.STRING_THREE);
        if (!resFlag) {
            return Result.error("新增月卡操作记录失败！");
        }


        return Result.ok("注销成功！");
    }

    private List<ParkCarMonthly> getParkCarMonthly(MonthlyCardDelayDto monthlyCardDelayDto) {
        QueryWrapper<ParkCarMonthly> parkCarMonthlyQueryWrapper = new QueryWrapper<>();
        parkCarMonthlyQueryWrapper.eq("park_code", monthlyCardDelayDto.getParkCode());
        parkCarMonthlyQueryWrapper.eq("monthly_card_id", monthlyCardDelayDto.getMonthlyCardId());
        parkCarMonthlyQueryWrapper.eq("status", "Y");
        List<ParkCarMonthly> parkCarMonthlys = iParkCarMonthlyService.list(parkCarMonthlyQueryWrapper);
        log.info("办理月卡延期，月租车信息------------------------------》:{}", parkCarMonthlys);
        return parkCarMonthlys;
    }

    private List<ParkSpace> getParkSpace(MonthlyCardDelayDto monthlyCardDelayDto) {
        QueryWrapper<ParkSpace> parkSpaceQueryWrapper = new QueryWrapper<>();
        parkSpaceQueryWrapper.eq("park_code", monthlyCardDelayDto.getParkCode());
        parkSpaceQueryWrapper.eq("status", "Y");
        parkSpaceQueryWrapper.eq("monthly_card_id", monthlyCardDelayDto.getMonthlyCardId());
        List<ParkSpace> parskSpace = parkSpaceService.list(parkSpaceQueryWrapper);
        log.info("办理月卡延期，查询绑定车位信息------------------------------》:{}", parskSpace);
        return parskSpace;
    }


    /**
     * 获取识别类型对应的车辆类型
     */
    @Override
    public ConfigCarType getCarType(String parkCode, int type) {
        QueryWrapper<ConfigCarType> configCarTypeQueryWrapper = new QueryWrapper<>();
        configCarTypeQueryWrapper.eq("park_code", parkCode);
        List<ConfigCarType> configCarTypeList = configCarTypeService.list(configCarTypeQueryWrapper);
        for (ConfigCarType configCarType : configCarTypeList) {
            configCarType.getCarTypeNo();
            List<String> list = Arrays.asList(configCarType.getCarTypeNo().split(","));
            if (list.contains(String.valueOf(type))) {
                return configCarType;
            }
        }
        return null;
    }


    /**
     * 月卡延期
     *
     * @param monthlyCardDelayDto
     * @return
     */
    @Override
    @CacheEvict(value = {"monthly:cardAndPackage"}, allEntries = true)
    public Result updateMonthlyCardDelay(MonthlyCardDelayDto monthlyCardDelayDto) {
        log.info("办理月卡延期，传入参数为------------------------------》:{}", JSONObject.toJSONString(monthlyCardDelayDto));

        MonthlyCardInfo monthlyCardInfo = this.getById(monthlyCardDelayDto.getMonthlyCardId());
        MonthlyCardInfo oldMonthlyCardInfo = new MonthlyCardInfo();
        BeanUtils.copyProperties(monthlyCardInfo, oldMonthlyCardInfo);
        monthlyCardInfo.setMonthlyMoney(monthlyCardDelayDto.getMonthlyMoney());
        monthlyCardInfo.setRemark(monthlyCardDelayDto.getRemark());
        MonthlyPackageInfo packageInfo = iMonthlyPackageInfoService.getById(monthlyCardInfo.getPackageId());
        QueryWrapper<MonthlyCarConfig> monthlyCarConfigQueryWrapper = new QueryWrapper<>();
        monthlyCarConfigQueryWrapper.eq("park_code", monthlyCardDelayDto.getParkCode());
        // 获取月租车信息
        boolean resFlag = true;
        List<ParkCarMonthly> parkCarMonthlys = getParkCarMonthly(monthlyCardDelayDto);
        List<String> plateNos = parkCarMonthlys.stream().map(ParkCarMonthly::getPlateNo).distinct().collect(Collectors.toList());
        List<String> areaList = parkCarMonthlys.stream().map(ParkCarMonthly::getAreaId).distinct().collect(Collectors.toList());
//        // 查询绑定车位
//        List<ParkSpace> parskSpace = getParkSpace(monthlyCardDelayDto);
//        // 更新月租车和车位信息,只有跳延更新开始时间
//        if (packageInfo.getOverdueDelayWay() == JddConstant.IntNumber.INT_TWO) {
//            parkCarMonthlys.stream().forEach(f -> f.setStartTime(monthlyCardDelayDto.getBeginTime()));
//            parskSpace.stream().forEach(f -> f.setStartTime(monthlyCardDelayDto.getBeginTime()));
//            monthlyCardInfo.setBeginTime(monthlyCardDelayDto.getBeginTime());
//        }
//        parkCarMonthlys.stream().forEach(f -> f.setEndTime(monthlyCardDelayDto.getEndTime()));
//        parskSpace.stream().forEach(f -> f.setEndTime(monthlyCardDelayDto.getEndTime()));
        monthlyCardInfo.setEndTime(monthlyCardDelayDto.getEndTime());
        // 更新月卡，更新车位，更新月租车，更新操作记录
        LoginUser loginUser = LoginUserUtils.getLoginUser();
        if (null != loginUser) {
            monthlyCardInfo.setUpdateUserId(loginUser.getUsername());
            monthlyCardInfo.setUpdateUserName(loginUser.getRealname());
        }
        monthlyCardInfo.setUpdateTime(new Date());
        resFlag = this.updateById(monthlyCardInfo);

        if (!resFlag) {
            return Result.error("更新monthlyCardInfo失败！");
        }


        getMonthlyCardEditInfo(monthlyCardInfo, JddConstant.StringNumber.STRING_TWO);
        // 是否有未占用车位
        QueryWrapper<ParkSpace> parkSpaceQueryWrapper = new QueryWrapper<>();
        parkSpaceQueryWrapper.eq("park_code", monthlyCardDelayDto.getParkCode());
        parkSpaceQueryWrapper.eq("park_status", JddConstant.StringNumber.STRING_ZERO);
        parkSpaceQueryWrapper.eq("monthly_card_id", monthlyCardInfo.getId());
        List<ParkSpace> parkSpaces = parkSpaceService.list(parkSpaceQueryWrapper);

        // 在场车辆查询
        List<ParkCarEnterLog> parkCarEnterLogs = getList(monthlyCardInfo.getParkCode(),plateNos,areaList);

        log.info("办理月卡延期，需要转卡的在场信息------------------------------》:{}", parkCarEnterLogs);
        if (CollectionUtil.isEmpty(parkCarEnterLogs)) {

            return Result.ok("延期成功！");
        }
        List<MonthlyCarTypeConvert> monthlyCarTypeConverts = new ArrayList<>();
        int count = 0;
        for (ParkCarEnterLog parkCarEnterLog : parkCarEnterLogs) {
            // 查询临时车入场的车，同一辆车入场记录只分配同一个车位即可，月租车入场的记录，无需分配车位
            if (StringUtils.isBlank(parkCarEnterLog.getParkNumber())) {
                if (count >= parkSpaces.size()) {
                    break;
                }
                count = dealSamePlateNoPlace(parkSpaces, parkCarEnterLog, count, areaList, monthlyCardInfo);
            }
            // 新增入场记录
            parkCarEnterLog.setId(SnowFlakeUtil.getId());
            parkCarEnterLog.setCarNature(JddConstant.StringNumber.STRING_ONE);
            parkCarEnterLog.setCarTypeName(packageInfo.getMonthlyTypeName());
            parkCarEnterLog.setCarTypeId(packageInfo.getMonthlyTypeId());
            parkCarEnterLog.setEnterType(JddConstant.IntNumber.INT_ZERO);
            parkCarEnterLog.setCreateTime(new Date());
            // 如果顺延，插入入场记录入场时间加1s，车辆类型为月租车
            if (packageInfo.getOverdueDelayWay() == JddConstant.IntNumber.INT_ONE) {
                String time = DateUtil.addSecond(parkCarEnterLog.getCarEnterTime(), JddConstant.IntNumber.INT_ONE);
                parkCarEnterLog.setCarEnterTime(time);
                parkCarEnterLog.setMonthlyCardId(monthlyCardInfo.getId());
                parkCarEnterLog.setIsTransfer(JddConstant.StringNumber.STRING_TWO);
                // 还原原入场记录的车位编号
                iparkCarEnterLogService.save(parkCarEnterLog);

                ParkCarEnterLogSyncV3Vo entity = new ParkCarEnterLogSyncV3Vo();
				entity.setParkCarEnterLogStr(JSON.toJSONString(parkCarEnterLog));
				entity.setParkStatus(JddConstant.ParkSpace.PARKSTATUS_ZERO);
                String url = "";				try {
					sdkIdentifyResultPushLogV3Service.sendMessageV3(entity,url);
				} catch (IOException e) {
					e.printStackTrace();
					log.error("月租车顺延上传入场记录错误->{}",e);
				}
            } else {
                // 处理跳延
                dealDelayLogs(monthlyCardInfo, parkCarEnterLog, oldMonthlyCardInfo, packageInfo);
                MonthlyCarTypeConvert monthlyCarTypeConvert = getMonthlyCarTypeConvert(monthlyCardInfo, parkCarEnterLog, packageInfo);
                monthlyCarTypeConverts.add(monthlyCarTypeConvert);
            }
        }
        resFlag = monthlyCarTypeConvertService.saveBatch(monthlyCarTypeConverts);

        if (!resFlag) {
            return Result.error("新增转卡记录失败");
        }

        return Result.ok("更新月卡信息成功！");
    }

    /**
     * 最近的一条入场记录，是否在指定区域内
     * @param parkCode
     * @param plateNos
     * @param areaList
     * @return
     */
    @Override
    public List<ParkCarEnterLog> getList(String parkCode, List<String> plateNos, List<String> areaList) {
        QueryWrapper<ParkCarEnterLog> parkCarEnterLogQueryWrapper = new QueryWrapper<>();
        parkCarEnterLogQueryWrapper.eq("park_code", parkCode);
        parkCarEnterLogQueryWrapper.eq("is_out", JddConstant.StringNumber.STRING_ZERO);
        parkCarEnterLogQueryWrapper.eq("enter_type", 0);
        parkCarEnterLogQueryWrapper.in("plate_no", plateNos);
        parkCarEnterLogQueryWrapper.orderByAsc("car_enter_time");
        List<ParkCarEnterLog> parkCarEnterLogList = iparkCarEnterLogService.list(parkCarEnterLogQueryWrapper);
        log.info("办理月卡延期，是否有在场的信息------------------------------》:{}", parkCarEnterLogList);
        Map<String, ParkCarEnterLog> newMap = new HashMap();
        for (ParkCarEnterLog parkCarEnterLog : parkCarEnterLogList) {
            newMap.put(parkCarEnterLog.getPlateNo(), parkCarEnterLog);
        }
        List<ParkCarEnterLog> carEnterLogs = new ArrayList<>();
        for (String key : newMap.keySet()) {
            carEnterLogs.add(newMap.get(key));
        }
        List<ParkCarEnterLog> enterLogList = new ArrayList<>();
        for (ParkCarEnterLog parkCarEnterLog : carEnterLogs) {
            if (areaList.contains(parkCarEnterLog.getAreaId())) {
                enterLogList.add(parkCarEnterLog);
            }
        }
        List<ParkCarEnterLog> parkCarEnterLogs = enterLogList.stream()
                .sorted(Comparator.comparing(ParkCarEnterLog::getCarEnterTime))
                .collect(Collectors.toList());
        return parkCarEnterLogs;
    }

    /**
     * 处理跳延时，在场记录的处理
     *
     * @param monthlyCardInfo
     * @param parkCarEnterLog
     * @param newMonthlyCardInfo
     */
    private void dealDelayLogs(MonthlyCardInfo newMonthlyCardInfo, ParkCarEnterLog parkCarEnterLog, MonthlyCardInfo monthlyCardInfo, MonthlyPackageInfo packageInfo) {
    	List<ParkCarEnterLog> list = new ArrayList<ParkCarEnterLog>();
    	// 跳延,入场时间在月卡结束时间之后，并在新月卡开始之后，新增转卡记录，月租车入场，入场时间+1s
		if (monthlyCardInfo.getEndTime().before(DateUtil.fomatDateTime(parkCarEnterLog.getCarEnterTime()))
                && newMonthlyCardInfo.getBeginTime().before(DateUtil.fomatDateTime(parkCarEnterLog.getCarEnterTime()))) {
            parkCarEnterLog.setIsTransfer(JddConstant.StringNumber.STRING_TWO);
            String time = DateUtil.addSecond(parkCarEnterLog.getCarEnterTime(), JddConstant.IntNumber.INT_ONE);
            parkCarEnterLog.setCarEnterTime(time);
            parkCarEnterLog.setMonthlyCardId(monthlyCardInfo.getId());
            iparkCarEnterLogService.save(parkCarEnterLog);
            list.add(parkCarEnterLog);
        }
        // 跳延,入场时间在月卡结束时间之后，并在新月卡开始之前，新增欲转卡记录，月租车入场，入场时间新月租开始时间
        else if (monthlyCardInfo.getEndTime().before(DateUtil.fomatDateTime(parkCarEnterLog.getCarEnterTime()))
                && newMonthlyCardInfo.getBeginTime().after(DateUtil.fomatDateTime(parkCarEnterLog.getCarEnterTime()))) {
            parkCarEnterLog.setIsTransfer(JddConstant.StringNumber.STRING_ONE);
            parkCarEnterLog.setCarEnterTime(DateUtil.fomatDateTimeStr(newMonthlyCardInfo.getBeginTime()));
            parkCarEnterLog.setMonthlyCardId(monthlyCardInfo.getId());
            iparkCarEnterLogService.save(parkCarEnterLog);
            list.add(parkCarEnterLog);
        }
		// 跳延,入场时间在月卡结束时间之前，插入两条记录，补一条临时车入场记录,入场时间为旧月卡结束时间，补一条月卡入场记录
        else {
            // 补临时车入场
            parkCarEnterLog.setIsTransfer(JddConstant.StringNumber.STRING_TWO);
            parkCarEnterLog.setCarNature(JddConstant.StringNumber.STRING_ZERO);
            parkCarEnterLog.setCarEnterTime(DateUtil.fomatDateTimeStr(monthlyCardInfo.getEndTime()));
            parkCarEnterLog.setMonthlyCardId("");
            ConfigCarType configCarType = this.getCarType(parkCarEnterLog.getParkCode(), Integer.valueOf(parkCarEnterLog.getCarTypeNo()));
            if (null != configCarType) {
                parkCarEnterLog.setCarTypeId(configCarType.getId());
                parkCarEnterLog.setCarTypeName(configCarType.getCarTypeName());
            }
            // 月租车入场记录 parkCarEnterLog;
            ParkCarEnterLog newParkCarEnterLog = new ParkCarEnterLog();
            BeanUtils.copyProperties(parkCarEnterLog, newParkCarEnterLog);
            newParkCarEnterLog.setId(SnowFlakeUtil.getId());
            newParkCarEnterLog.setCarEnterTime(DateUtil.fomatDateTimeStr(newMonthlyCardInfo.getBeginTime()));
            newParkCarEnterLog.setCarNature(JddConstant.StringNumber.STRING_ONE);
            newParkCarEnterLog.setCarTypeName(packageInfo.getMonthlyTypeName());
            newParkCarEnterLog.setMonthlyCardId(monthlyCardInfo.getId());
            newParkCarEnterLog.setCarTypeId(packageInfo.getMonthlyTypeId());
            // 今天在新月卡之前，补欲转卡（不知何时出场）
            if (new Date().before(newMonthlyCardInfo.getBeginTime())) {
                newParkCarEnterLog.setIsTransfer(JddConstant.StringNumber.STRING_ONE);
            } else {
                // 今天在新月卡之前，补欲转卡
                newParkCarEnterLog.setIsTransfer(JddConstant.StringNumber.STRING_TWO);
            }
            // 临时车入场不需要分配车位
            parkCarEnterLog.setParkNumber("");
            iparkCarEnterLogService.save(parkCarEnterLog);
            iparkCarEnterLogService.save(newParkCarEnterLog);
            list.add(parkCarEnterLog);
            list.add(newParkCarEnterLog);
        }
        if(list.size() > 0){
        	try {
				for(ParkCarEnterLog parkCarEnterLogImport : list){
					ParkCarEnterLogSyncV3Vo entity = new ParkCarEnterLogSyncV3Vo();
					entity.setParkCarEnterLogStr(JSON.toJSONString(parkCarEnterLogImport));
					// 月租车
					if(StringUtils.isNotBlank(parkCarEnterLogImport.getParkNumber())){
						entity.setParkStatus(JddConstant.ParkSpace.PARKSTATUS_ONE);
						entity.setSourceAreaId(parkCarEnterLogImport.getAreaId());
					}else{
						// 临时车
						entity.setParkStatus(JddConstant.ParkSpace.PARKSTATUS_ZERO);
					}
                    String url = "";
					sdkIdentifyResultPushLogV3Service.sendMessageV3(entity,url);
				}
			} catch (Exception e) {
				e.printStackTrace();
				log.info("新增月租车上传到云端失败->{}",e);
			}
        }
    }

    /**
     * 处理同一车牌号，多个入场记录，只分配一个车位,月租车
     *
     * @param parkSpaces
     * @param parkCarEnterLog
     * @param count
     * @param areaList
     */
    private Integer dealSamePlateNoPlace(List<ParkSpace> parkSpaces, ParkCarEnterLog parkCarEnterLog, int count, List<String> areaList, MonthlyCardInfo monthlyCardInfo) {
        ParkSpace parkSpace = parkSpaces.get(count);
        parkSpace.setPlateNo(parkCarEnterLog.getPlateNo());
        parkSpace.setMonthlyCode(monthlyCardInfo.getMonthlyCode());
        parkSpace.setMonthlyCardId(monthlyCardInfo.getId());
        parkSpace.setParkStatus("1");
        parkSpaceService.updateById(parkSpace);
        List<ParkSpace> parkSpaceList =new LinkedList<>();
        parkSpaceList.add(parkSpace);
        monthlyCardInfo.setParkSpaceList(parkSpaceList);
        QueryWrapper<ParkCarEnterLog> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("park_code", parkCarEnterLog.getParkCode());
        queryWrapper.eq("plate_no", parkCarEnterLog.getPlateNo());
        queryWrapper.eq("car_nature", "1");
        queryWrapper.in("area_id", areaList);
        queryWrapper.orderByDesc("create_time");
        List<ParkCarEnterLog> logList = iparkCarEnterLogService.list(queryWrapper);
        if (CollectionUtils.isNotEmpty(logList)) {
            parkCarEnterLog.setParkNumber(logList.get(0).getParkNumber());
            return count;
        } else {
            parkCarEnterLog.setParkNumber(parkSpace.getParkNumber());
            return count + 1;
        }
    }


    /**
     * 编辑月卡
     *
     * @param monthlyCardInfo
     * @return
     */
    @Override
    @CacheEvict(value = {"monthly:cardAndPackage"}, allEntries = true)
    public Result<MonthlyCardInfo> editMonthlyCard(MonthlyCardInfo monthlyCardInfo) {

        MonthlyCardInfo monthlyCardInfoEntity = this.getById(monthlyCardInfo.getId());
        if (monthlyCardInfoEntity == null) {
            return Result.error("未找到对应月卡信息");
        }
        boolean resFlag = true;
        // 删除车牌号,走注销逻辑
        List<String> deletePlateNos = monthlyCardInfo.getDeletePlateNos();
        if (CollectionUtil.isNotEmpty(deletePlateNos)) {
            deletePlateNo(deletePlateNos, monthlyCardInfo);
        }
        // 新增车牌号
        List<String> addPlateNo = monthlyCardInfo.getAddPlateNos();
        if (CollectionUtil.isNotEmpty(addPlateNo)) {
            // 查询绑定车位信息
            QueryWrapper<ParkSpace> parkSpaceQueryWrapper = new QueryWrapper<>();
            parkSpaceQueryWrapper.eq("park_code", monthlyCardInfo.getParkCode());
            parkSpaceQueryWrapper.eq("monthly_card_id", monthlyCardInfo.getId());
            List<ParkSpace> spaces = parkSpaceService.list(parkSpaceQueryWrapper);
            log.info("编辑页面，查询绑定车位信息---------------------》:{}", spaces);
            dealInParkCar(spaces, addPlateNo, monthlyCardInfo);
        }
        // 1.修改月卡
        LoginUser loginUser = LoginUserUtils.getLoginUser();
        if (null != loginUser) {
            monthlyCardInfo.setUpdateUserId(loginUser.getUsername());
            monthlyCardInfo.setUpdateUserName(loginUser.getRealname());
        }
        monthlyCardInfo.setUpdateTime(new Date());
        resFlag = this.updateById(monthlyCardInfo);
        //TODO 返回false说明什么？
        if (!resFlag) {
            return Result.error("修改失败!");
        }
        // 3.新增月卡操作记录
        getMonthlyCardEditInfo(monthlyCardInfo, JddConstant.StringNumber.STRING_FIVE);
        return Result.ok("修改成功");
    }


    /**
     * 删除的关联车牌号的的月租车信息
     *
     * @param
     * @return
     */
    public void deletePlateNo(List<String> plateNos, MonthlyCardInfo monthlyCardInfo) {
        // 删除租车信息
        log.info("删除关联车位信息，传入参数--------------------------》:{}", plateNos);
        QueryWrapper<ParkCarMonthly> parkCarMonthlyQueryWrapper = new QueryWrapper<>();
        parkCarMonthlyQueryWrapper.eq("monthly_card_id", monthlyCardInfo.getId());
        parkCarMonthlyQueryWrapper.in("plate_no", plateNos);
        List<ParkCarMonthly> parkCarMonthlyList = iParkCarMonthlyService.list(parkCarMonthlyQueryWrapper);
        List<String> araIds = parkCarMonthlyList.stream().map(ParkCarMonthly::getAreaId).distinct().collect(Collectors.toList());
        // 获取删除的场内车辆月租车入场记录
        List<ParkCarEnterLog> fieldParkCarEnterLog = getList(monthlyCardInfo.getParkCode(),plateNos,araIds);
        log.info("删除的场内车辆月租车牌号的入场记录为---------:{}", fieldParkCarEnterLog);
        if (CollectionUtil.isNotEmpty(fieldParkCarEnterLog)) {
            MonthlyPackageInfo monthlyPackageInfo = iMonthlyPackageInfoService.getById(monthlyCardInfo.getPackageId());
            List<ParkCarEnterLog> parkCarEnterLogs = new ArrayList<>();
            List<MonthlyCarTypeConvert> monthlyCarTypeConverts = new ArrayList<>();
            List<ParkSpace>parkSpaceList = new LinkedList<>();
            for (ParkCarEnterLog parkCarEnterLog : fieldParkCarEnterLog) {
                // 修改车牌号，删除原有车牌号的车位
                if (StringUtils.isNotEmpty(parkCarEnterLog.getParkNumber())) {
                    QueryWrapper<ParkSpace> queryWrapper1 = new QueryWrapper<>();
                    queryWrapper1.eq("monthly_card_id", monthlyCardInfo.getId());
                    queryWrapper1.eq("plate_no", parkCarEnterLog.getPlateNo());
                    queryWrapper1.eq("park_number", parkCarEnterLog.getParkNumber());
                    ParkSpace parkSpace = parkSpaceService.getOne(queryWrapper1);
                    parkSpace.setParkStatus("0");
                    parkSpace.setPlateNo("");
                    parkSpaceService.updateById(parkSpace);
                    parkSpaceList.add(parkSpace);
                }
                ParkCarEnterLog newParkCarEnterLog = new ParkCarEnterLog();//parkCarEnterLog;
                BeanUtils.copyProperties(parkCarEnterLog, newParkCarEnterLog);
                newParkCarEnterLog.setId(SnowFlakeUtil.getId());
                // 判断月租是否过期,过期
                if (monthlyCardInfo.getEndTime().before(new Date()) &&
                        DateUtil.fomatDateTime(parkCarEnterLog.getCarEnterTime()).before(monthlyCardInfo.getEndTime())) {
                    newParkCarEnterLog.setCarEnterTime(DateUtil.fomatDateTimeStr(monthlyCardInfo.getEndTime()));
                }
                if (new Date().before(monthlyCardInfo.getEndTime())) {
                    newParkCarEnterLog.setCarEnterTime(DateUtil.fomatDateTimeStr(new Date()));
                }
                newParkCarEnterLog.setCreateTime(new Date());
                newParkCarEnterLog.setCarNature(JddConstant.StringNumber.STRING_ZERO);
                newParkCarEnterLog.setIsTransfer(JddConstant.StringNumber.STRING_TWO);
                ConfigCarType configCarType = this.getCarType(newParkCarEnterLog.getParkCode(), Integer.valueOf(newParkCarEnterLog.getCarTypeNo()));
                if (null != configCarType) {
                    newParkCarEnterLog.setCarTypeName(configCarType.getCarTypeName());
                    newParkCarEnterLog.setCarTypeId(configCarType.getId());
                }
                newParkCarEnterLog.setMonthlyCardId("");
                newParkCarEnterLog.setParkNumber("");
                parkCarEnterLogs.add(newParkCarEnterLog);
                //组装转卡记录
                MonthlyCarTypeConvert monthlyCarTypeConvert = getMonthlyCarTypeConvert(monthlyCardInfo, parkCarEnterLog, monthlyPackageInfo);
                monthlyCarTypeConverts.add(monthlyCarTypeConvert);
            }

            // 更新车位，插入入场，转卡
            iparkCarEnterLogService.saveBatch(parkCarEnterLogs);
            iMonthlyCarTypeConvertService.saveBatch(monthlyCarTypeConverts);
        }
        QueryWrapper<ParkCarMonthly> monthlyQueryWrapper = new QueryWrapper<>();
        monthlyQueryWrapper.eq("monthly_card_id", monthlyCardInfo.getId());
        monthlyQueryWrapper.in("plate_no", plateNos);
        iParkCarMonthlyService.remove(monthlyQueryWrapper);
    }


    /**
     * 新增入场转卡记录
     *
     * @param monthlyCarDto
     * @return
     */
    public Result addParkCarEnterInfo(MonthlyCardInfo monthlyCarDto, List<ParkSpace> parkSpaceList, List<ParkCarEnterLog> parkCarEnterLogs) {

        if (CollectionUtil.isNotEmpty(monthlyCarDto.getParkSpaceList())){
            monthlyCarDto.getParkSpaceList().clear();
        }
        log.info("生成月卡时，新增入场记录时传入参数--------------------------》:{}", monthlyCarDto);
        MonthlyPackageInfo monthlyPackageInfo = iMonthlyPackageInfoService.getById(monthlyCarDto.getPackageId());
        List<String> inSitePlateNo = parkCarEnterLogs.stream().map(ParkCarEnterLog::getPlateNo).distinct().collect(Collectors.toList());
        List<String> areaList = parkSpaceList.stream().map(ParkSpace::getAreaId).distinct().collect(Collectors.toList());
        //List<ParkSpace> parkSpaces = this.getFreeSpace(monthlyCarDto.getParkCode(), areaList);
        log.info("生成月卡时，区域信息 --------------------------》:{}", areaList);
        // log.info("开通区域未占用的车位----------------------------》:{}", parkSpaces);

        if (areaList.size() > 1 && inSitePlateNo.size() > 1) {
            return Result.ok("开通成功.多区域的情况下,不允许多车多位的月租车立即生效");
        }
        if (CollectionUtil.isEmpty(inSitePlateNo)) {
            return Result.ok("无空余车位，开通成功");
        }
        TurnCardVo turnCardVo = openGetParkCarEnterLog(monthlyCarDto, inSitePlateNo, parkSpaceList, parkCarEnterLogs, monthlyPackageInfo);
        iparkCarEnterLogService.saveBatch(turnCardVo.getParkCarEnterLogs());
        monthlyCarTypeConvertService.saveBatch(turnCardVo.getMonthlyCarTypeConverts());
      //  parkSpaceService.updateBatchById(turnCardVo.getParkSpaceList());
        return Result.ok("新增成功！");
    }


    /**
     * 转卡记录
     *
     * @param monthlyCardInfo
     * @param plateNos
     * @param notParkSpaces
     * @param parkCarEnterLogs
     * @param monthlyPackageInfo
     * @return
     */
    public TurnCardVo openGetParkCarEnterLog(MonthlyCardInfo monthlyCardInfo, List<String> plateNos, List<ParkSpace> notParkSpaces,
                                             List<ParkCarEnterLog> parkCarEnterLogs, MonthlyPackageInfo monthlyPackageInfo) {
        log.info("进入开通转卡逻辑，传入参数notParkSpaces-----------------》：{}", notParkSpaces);
        TurnCardVo turnCardVo = new TurnCardVo();
        List<ParkCarEnterLog> addParkCarEnterLogs = new ArrayList<>();
        List<MonthlyCarTypeConvert> monthlyCarTypeConverts = new ArrayList<>();
        List<String> areaIdList = notParkSpaces.stream().map(ParkSpace::getAreaId).distinct().collect(Collectors.toList());
        int count = 0;
        if (areaIdList.size() > 1 && plateNos.size() > 1) {
            log.info("多车多位多区域，不处理");
            turnCardVo.setParkCarEnterLogs(addParkCarEnterLogs);
            turnCardVo.setMonthlyCarTypeConverts(monthlyCarTypeConverts);
            return turnCardVo;
        }
        for (ParkCarEnterLog parkCarEnterLog : parkCarEnterLogs) {
            // 遍历入场纪录，随机分配车位，车位分配完退出
            if (count >= notParkSpaces.size()) {
                log.info("车位分配完退出，循环");
                break;
            }
            // 查询同一辆车的所有入场记录,同一辆车分配同一个车位即可
            if (StringUtils.isBlank(parkCarEnterLog.getParkNumber())) {
                count = dealSamePlateNoPlace(notParkSpaces, parkCarEnterLog, count, areaIdList, monthlyCardInfo);
            }
            // 新增入场记录
            parkCarEnterLog.setId(SnowFlakeUtil.getId());
            parkCarEnterLog.setCarTypeId(monthlyPackageInfo.getMonthlyTypeId());
            parkCarEnterLog.setCarTypeName(monthlyPackageInfo.getMonthlyTypeName());
            parkCarEnterLog.setCarNature("1");
            parkCarEnterLog.setEnterType(JddConstant.IntNumber.INT_ZERO);
            parkCarEnterLog.setCreateTime(new Date());
            parkCarEnterLog.setMonthlyCardId(monthlyCardInfo.getId());
            // 若入场时间在月卡开始之后，新增转卡记录，否则，生成欲转卡记录
            if (DateUtil.fomatDateTime(parkCarEnterLog.getCarEnterTime()).after(monthlyCardInfo.getBeginTime())
                    && DateUtil.fomatDateTime(parkCarEnterLog.getCarEnterTime()).before(monthlyCardInfo.getEndTime())) {
                String time = DateUtil.addSecond(parkCarEnterLog.getCarEnterTime(), JddConstant.IntNumber.INT_ONE);
                parkCarEnterLog.setCarEnterTime(time);
                parkCarEnterLog.setIsTransfer(JddConstant.StringNumber.STRING_TWO);
            } else {
                parkCarEnterLog.setIsTransfer(JddConstant.StringNumber.STRING_ONE);
                parkCarEnterLog.setCarEnterTime(DateUtil.fomatDateTimeStr(monthlyCardInfo.getBeginTime()));
            }
            addParkCarEnterLogs.add(parkCarEnterLog);
            MonthlyCarTypeConvert monthlyCarTypeConvert = getMonthlyCarTypeConvert(monthlyCardInfo, parkCarEnterLog, monthlyPackageInfo);
            monthlyCarTypeConverts.add(monthlyCarTypeConvert);
        }
        turnCardVo.setParkCarEnterLogs(addParkCarEnterLogs);
        turnCardVo.setMonthlyCarTypeConverts(monthlyCarTypeConverts);
        return turnCardVo;
    }

    /**
     * 封装转卡信息
     *
     * @param monthlyCardInfo
     * @param parkCarEnterLog
     * @param monthlyPackageInfo
     * @return
     */
    @Override
    public MonthlyCarTypeConvert getMonthlyCarTypeConvert(MonthlyCardInfo monthlyCardInfo, ParkCarEnterLog
            parkCarEnterLog, MonthlyPackageInfo monthlyPackageInfo) {
        MonthlyCarTypeConvert monthlyCarTypeConvert = new MonthlyCarTypeConvert();
        monthlyCarTypeConvert.setId(SnowFlakeUtil.getId());
        monthlyCarTypeConvert.setParkCode(monthlyCardInfo.getParkCode());
        monthlyCarTypeConvert.setParkName(monthlyCardInfo.getParkName());
        monthlyCarTypeConvert.setBatchNumber(parkCarEnterLog.getBatchNumber());
        monthlyCarTypeConvert.setCarEnterId(parkCarEnterLog.getId());
        monthlyCarTypeConvert.setAreaId(parkCarEnterLog.getAreaId());
        monthlyCarTypeConvert.setPlateNo(parkCarEnterLog.getPlateNo());
        monthlyCarTypeConvert.setMonthlyTypeId(monthlyPackageInfo.getMonthlyTypeId());
        monthlyCarTypeConvert.setMonthlyTypeName(monthlyPackageInfo.getMonthlyTypeName());
        monthlyCarTypeConvert.setBeginTime(new Date());
        return monthlyCarTypeConvert;
    }


    /**
     * 组装月卡信息表
     *
     * @param monthlyCardInfo
     * @return com.jdd.modules.parking.entity.MonthlyCardInfo
     * @date 2021/11/19 18:24:06
     * @version 1.0
     */
    public boolean getMonthlyCardInfo(MonthlyCardInfo monthlyCardInfo) {
        LoginUser loginUser = LoginUserUtils.getLoginUser();
        if (StringUtils.isBlank(monthlyCardInfo.getId())){
            monthlyCardInfo.setId(SnowFlakeUtil.getId());
        }
        monthlyCardInfo.setParkCode(monthlyCardInfo.getParkCode());
        monthlyCardInfo.setParkName(monthlyCardInfo.getParkName());
        monthlyCardInfo.setMonthlyStatus(JddConstant.IntNumber.INT_ONE);
        if (null != loginUser) {
            monthlyCardInfo.setCreateUserId(loginUser.getUsername());
            monthlyCardInfo.setCreateUserName(loginUser.getRealname());
        }
        String mothlyCode = getMonthlyCode(monthlyCardInfo.getParkCode());
        monthlyCardInfo.setMonthlyCode(mothlyCode);
        if (null == monthlyCardInfo.getThroughAuthorityId()) {
            monthlyCardInfo.setThroughAuthorityId(null);
            monthlyCardInfo.setThroughAuthorityName(null);
        }
        monthlyCardInfo.setCreateTime(new Date());
        log.info("新增月卡信息为==============================>:{}", monthlyCardInfo);
        return this.save(monthlyCardInfo);
    }


    /**
     * 注销时 查询绑定月租车车牌号 是否有在场的入场记录
     *
     * @return
     * @author qilina
     */
    private List<ParkCarEnterLog> getPlateNoInPark(String parkCode, String monthlyCardId) {
        // 查询月卡绑定的区域信息和车位信息
        List<ParkCarMonthly> parkCarMonthlyList = getPlateNoInfo(monthlyCardId);
        List<String> areaList = parkCarMonthlyList.stream().map(ParkCarMonthly::getAreaId).distinct().collect(Collectors.toList());
        log.info("查询区域信息，areaList--------------------------》:{}", areaList);
        List<String> plateNos = parkCarMonthlyList.stream().map(ParkCarMonthly::getPlateNo).distinct().collect(Collectors.toList());
        QueryWrapper<ParkCarEnterLog> parkCarEnterLogQueryWrapper = new QueryWrapper<>();
        parkCarEnterLogQueryWrapper.eq("park_code", parkCode);
        parkCarEnterLogQueryWrapper.eq("is_out", JddConstant.StringNumber.STRING_ZERO);
        parkCarEnterLogQueryWrapper.in("plate_no", plateNos);
        parkCarEnterLogQueryWrapper.in("area_id", areaList);
        parkCarEnterLogQueryWrapper.orderByAsc("car_enter_time");
        List<ParkCarEnterLog> list = iparkCarEnterLogService.list(parkCarEnterLogQueryWrapper);
        Map<String, ParkCarEnterLog> newMap = new HashMap();
        for (ParkCarEnterLog parkCarEnterLog : list) {
            newMap.put(parkCarEnterLog.getPlateNo(), parkCarEnterLog);
        }
        List<ParkCarEnterLog> carEnterLogs = new ArrayList<>();
        for (String key : newMap.keySet()) {
            carEnterLogs.add(newMap.get(key));
        }
        return carEnterLogs;
    }



    /**
     * 月卡新信息
     *
     * @param id
     * @return
     */
    public List<ParkCarMonthly> getPlateNoInfo(String id) {
        QueryWrapper<ParkCarMonthly> parkCarMonthlyQueryWrapper = new QueryWrapper<>();
        parkCarMonthlyQueryWrapper.select("DISTINCT(plate_no) AS plateNo", "area_id AS areaId");
        parkCarMonthlyQueryWrapper.eq("monthly_card_id", id);
        List<ParkCarMonthly> parkCarMonthlyList = iParkCarMonthlyService.list(parkCarMonthlyQueryWrapper);
        return parkCarMonthlyList;
    }

    /**
     * 月卡编号生成规则
     *
     * @param parkCode
     * @return
     */
    @Override
    public String getMonthlyCode(String parkCode) {
        String monthlyCode;
        QueryWrapper<MonthlyCardInfo> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("park_code", parkCode);
        List<MonthlyCardInfo> monthlyCardInfoList = this.list(queryWrapper);
        if (CollectionUtil.isEmpty(monthlyCardInfoList)) {
            return "P000" + 1;
        }
        List<MonthlyCardInfo> monthlyCardInfos = monthlyCardInfoList.stream()
                .sorted(Comparator.comparing(MonthlyCardInfo::getMonthlyCode).reversed())
                .collect(Collectors.toList());
        monthlyCode = monthlyCardInfos.get(0).getMonthlyCode();
        int num = Integer.parseInt(monthlyCode.substring(1));
        num++;
        if (num < 10) {
            monthlyCode = "P000" + num;
        } else if (num >= 10 && num < 100) {
            monthlyCode = "P00" + num;
        } else if (num >= 100 && num < 1000) {
            monthlyCode = "P0" + num;
        } else if (num >= 1000 && num < 10000) {
            monthlyCode = "P" + num;
        } else {
        }
        log.info("生成的新的月卡编号为-------------》:{}", monthlyCode);
        return monthlyCode;
    }
    /**
     * 封装月租车实体信息
     *
     * @param parkSpaces
     * @param plateNoList
     * @param monthlyCardInfo
     * @return
     */
    @Override
    public List<ParkCarMonthly> getParkCarMonthlyEntity(List<ParkSpace> parkSpaces, List<String> plateNoList, MonthlyCardInfo monthlyCardInfo) {
        List<ParkCarMonthly> list = new ArrayList<>();
        ParkCarMonthly parkCarMonthly = new ParkCarMonthly();
        // 查询是否有相关的配置信息
        MonthlyPackageInfo monthlyPackageInfo = iMonthlyPackageInfoService.getById(monthlyCardInfo.getPackageId());
        parkCarMonthly.setId(SnowFlakeUtil.getId());
        parkCarMonthly.setParkCode(monthlyCardInfo.getParkCode());
        parkCarMonthly.setStartTime(monthlyCardInfo.getBeginTime());
        parkCarMonthly.setEndTime(monthlyCardInfo.getEndTime());
        parkCarMonthly.setMonthlyCardId(monthlyCardInfo.getId());
        parkCarMonthly.setParkName(monthlyCardInfo.getParkName());
        parkCarMonthly.setStatus("Y");
        parkCarMonthly.setAddress(monthlyCardInfo.getAddress());
        parkCarMonthly.setMobile(monthlyCardInfo.getTelephone());
        LoginUser sysUser = LoginUserUtils.getLoginUser();
        if (sysUser!=null){
            parkCarMonthly.setCreateUser(sysUser.getRealname());
        }
        parkCarMonthly.setUserName(monthlyCardInfo.getCarOwnerName());
        if (monthlyPackageInfo.getSpaceFlag().equals(JddConstant.IntNumber.INT_TWO)) {
            parkCarMonthly.setIsMulti("Y");
        } else {
            parkCarMonthly.setIsMulti("N");
        }
        for (ParkSpace carPlace : parkSpaces) {
            for (String plateNo : plateNoList) {
                ParkCarMonthly newParkCarMonthly = new ParkCarMonthly();
                BeanUtils.copyProperties(parkCarMonthly, newParkCarMonthly);
                newParkCarMonthly.setId(SnowFlakeUtil.getId());
                newParkCarMonthly.setAreaId(carPlace.getAreaId());
                newParkCarMonthly.setCarTypeId(carPlace.getSpaceType());
                newParkCarMonthly.setAreaName(carPlace.getAreaName());
                newParkCarMonthly.setParkNumber(carPlace.getParkNumber());
                newParkCarMonthly.setPlateNo(plateNo);
                if (null != newParkCarMonthly) {
                    list.add(newParkCarMonthly);
                }
            }
        }
        log.info("生成的月租车位信息为：---------->:{}", list);
        return list;
    }

	@Override
	public MonthlyCardAndPackageVo getCardInfoAndPackageInfo(String cardId) {
		return CollectionUtils.isNotEmpty(monthlyCardInfoMapper.selectCardInfoAndPackageInfo(cardId))
				? monthlyCardInfoMapper.selectCardInfoAndPackageInfo(cardId).get(0) : null;
	}

    /**
     * 组装月卡信息表
     *
     * @param monthlyCardInfo
     * @return com.jdd.modules.parking.entity.MonthlyCardInfo
     * @date 2021/11/19 18:24:06
     * @version 1.0
     */
    @Override
    public boolean getMonthlyCardInfo(MonthlyCardInfo monthlyCardInfo,ConfigParkInfo oneByParkCode) {
        LoginUser loginUser = LoginUserUtils.getLoginUser();
        monthlyCardInfo.setId(SnowFlakeUtil.getId());
        monthlyCardInfo.setParkCode(monthlyCardInfo.getParkCode());
        monthlyCardInfo.setParkName(monthlyCardInfo.getParkName());
        monthlyCardInfo.setMonthlyStatus(JddConstant.IntNumber.INT_ONE);
        if (null != loginUser) {
            monthlyCardInfo.setCreateUserId(loginUser.getUsername());
            monthlyCardInfo.setCreateUserName(loginUser.getRealname());
        }
        String mothlyCode = getMonthlyCode(monthlyCardInfo.getParkCode());
        monthlyCardInfo.setMonthlyCode(mothlyCode);
        if (null == monthlyCardInfo.getThroughAuthorityId()) {
            monthlyCardInfo.setThroughAuthorityId(null);
            monthlyCardInfo.setThroughAuthorityName(null);
        }
        monthlyCardInfo.setCreateTime(new Date());
        log.info("新增月卡信息为==============================>:{}", monthlyCardInfo);
        return this.save(monthlyCardInfo);
    }

    /**
     * 封装日志信息记录日志信息
     *
     * @param monthlyCardInfo
     * @return
     */
    @Override
     public boolean getMonthlyCardEditInfo(MonthlyCardInfo monthlyCardInfo, String optionsType) {
        //新增月卡延期记录
        MonthlyCardEditInfo monthlyCardEditInfo = new MonthlyCardEditInfo();
        monthlyCardEditInfo.setId(SnowFlakeUtil.getId());
        monthlyCardEditInfo.setParkCode(monthlyCardInfo.getParkCode());
        monthlyCardEditInfo.setParkName(monthlyCardInfo.getParkName());
        monthlyCardEditInfo.setOptionsType(optionsType);
        monthlyCardEditInfo.setMonthlyCardId(monthlyCardInfo.getId());
        monthlyCardEditInfo.setMonthlyCode(monthlyCardInfo.getMonthlyCode());
        monthlyCardEditInfo.setPackageId(monthlyCardInfo.getPackageId());
        monthlyCardEditInfo.setPackageName(monthlyCardInfo.getPackageName());
        monthlyCardEditInfo.setUserName(monthlyCardInfo.getCarOwnerName());
        monthlyCardEditInfo.setMonthlyDepartmentId(monthlyCardInfo.getMonthlyDepartmentId());
        monthlyCardEditInfo.setMonthlyDepartmentName(monthlyCardInfo.getMonthlyDepartmentName());
        monthlyCardEditInfo.setThroughAuthorityId(monthlyCardInfo.getThroughAuthorityId());
        monthlyCardEditInfo.setThroughAuthorityName(monthlyCardInfo.getThroughAuthorityName());
        monthlyCardEditInfo.setBusinessSource(JddConstant.StringNumber.STRING_ONE);
        monthlyCardEditInfo.setRemark(monthlyCardInfo.getRemark());
        LoginUser sysUser = LoginUserUtils.getLoginUser();
        monthlyCardEditInfo.setCreateUserId(sysUser.getUsername());
        monthlyCardEditInfo.setCreateUserName(sysUser.getRealname());
        monthlyCardEditInfo.setCreateTime(new Date());
        monthlyCardEditInfo.setPayTheFee(monthlyCardInfo.getMonthlyMoney());
        MonthlyPackageInfo monthlyPackageInfo = iMonthlyPackageInfoService.getById(monthlyCardInfo.getPackageId());
        monthlyCardEditInfo.setOverdueDelayWay(String.valueOf(monthlyPackageInfo.getOverdueDelayWay()));
        // 不是新增
        if (!JddConstant.StringNumber.STRING_FOUR.equals(optionsType)) {
            QueryWrapper<MonthlyCardEditInfo> monthlyCardEditInfoQueryWrapper = new QueryWrapper<>();
            monthlyCardEditInfoQueryWrapper.eq("monthly_card_id", monthlyCardInfo.getId());
            monthlyCardEditInfoQueryWrapper.orderByDesc("create_time");
            List<MonthlyCardEditInfo> monthlyCardEditInfos = iMonthlyCardEditInfoService.list(monthlyCardEditInfoQueryWrapper);
            monthlyCardEditInfo.setBeforeStartTime(monthlyCardEditInfos.get(0).getStartTime());
            monthlyCardEditInfo.setBeforeEndTime(monthlyCardEditInfos.get(0).getEndTime());
            monthlyCardEditInfo.setBeforeParkNumbers(monthlyCardEditInfos.get(0).getParkNumbers());
            monthlyCardEditInfo.setBeforePlateNos(monthlyCardEditInfos.get(0).getPlateNos());
            log.info("monthlyCardEditInfo=================================>：{}", monthlyCardEditInfo);
            QueryWrapper<ParkCarMonthly> monthlyQueryWrapper = new QueryWrapper<>();
            monthlyQueryWrapper.eq("monthly_card_id", monthlyCardInfo.getId());
            monthlyQueryWrapper.eq("park_code", monthlyCardInfo.getParkCode());
            List<ParkCarMonthly> list = iParkCarMonthlyService.list(monthlyQueryWrapper);
            List<String> plateNos = list.stream().map(ParkCarMonthly::getPlateNo).distinct().collect(Collectors.toList());
            // 如果车牌号大于100则只取100个车牌保存
            /*if(plateNos.size() > 100){
            	plateNos = plateNos.subList(0, 100);
            }*/
            List<String> parkNumbers = list.stream().map(ParkCarMonthly::getParkNumber).distinct().collect(Collectors.toList());
            // 如果车位号大于100则只取100个车位保存
            /*if(parkNumbers.size() > 100){
            	parkNumbers = parkNumbers.subList(0, 100);
            }*/

            String plateNo = "";
            String parkNumber = "";
            if(plateNos.size() > 99){
            	plateNo = StringUtils.join(plateNos.subList(0, 99).toArray(), ",") + " ...";
            }else{
            	plateNo = StringUtils.join(plateNos.toArray(), ",");
            }
            if(parkNumbers.size() > 99){
            	parkNumber = StringUtils.join(parkNumbers.subList(0, 99).toArray(), ",") + " ...";
            }else{
            	parkNumber = StringUtils.join(parkNumbers.toArray(), ",");
            }

            /*String plateNo = StringUtils.join(plateNos.toArray(), ",");
            String parkNumber = StringUtils.join(parkNumbers.toArray(), ",");*/
            // 注销
            if (JddConstant.StringNumber.STRING_THREE.equals(optionsType)) {
                monthlyCardEditInfo.setPayTheFee(monthlyCardInfo.getMonthlyMoney());
                return iMonthlyCardEditInfoService.save(monthlyCardEditInfo);
            }
            // 修改
            if (JddConstant.StringNumber.STRING_FIVE.equals(optionsType)) {
                monthlyCardEditInfo.setStartTime(monthlyCardEditInfos.get(0).getStartTime());
                monthlyCardEditInfo.setEndTime(monthlyCardEditInfos.get(0).getEndTime());
                monthlyCardEditInfo.setParkNumbers(parkNumber);
                monthlyCardEditInfo.setPlateNos(plateNo);
                return iMonthlyCardEditInfoService.save(monthlyCardEditInfo);
            }
            // 延期
            if (JddConstant.StringNumber.STRING_TWO.equals(optionsType)) {
                monthlyCardEditInfo.setStartTime(monthlyCardInfo.getBeginTime());
                monthlyCardEditInfo.setEndTime(monthlyCardInfo.getEndTime());
                monthlyCardEditInfo.setParkNumbers(parkNumber);
                monthlyCardEditInfo.setPlateNos(plateNo);
                if (null != monthlyCardInfo.getMonthlyMoney()) {
                    monthlyCardEditInfo.setPayTheFee(monthlyCardInfo.getMonthlyMoney());
                }
                return iMonthlyCardEditInfoService.save(monthlyCardEditInfo);
            }
        }

        // 新增车牌
        List<String> plateNoList = monthlyCardInfo.getPlateNoList();
        String plateNo = StringUtils.join(plateNoList.toArray(), ",");
        monthlyCardEditInfo.setPlateNos(plateNo);
        // 车位
        List<String> monthlyCardIdList = monthlyCardInfo.getParkNumberList();
        List<String> parkNumbers = new ArrayList<>();
        for (String id : monthlyCardIdList) {
            ParkSpace parkSpace = parkSpaceService.getById(id);
            if (null != parkSpace) {
                parkNumbers.add(parkSpace.getParkNumber());
            }
        }
        String parkNumber = StringUtils.join(parkNumbers.toArray(), ",");
        monthlyCardEditInfo.setParkNumbers(parkNumber);
        monthlyCardEditInfo.setStartTime(monthlyCardInfo.getBeginTime());
        monthlyCardEditInfo.setEndTime(monthlyCardInfo.getEndTime());
        monthlyCardEditInfo.setPaymentChannel(JddConstant.StringNumber.STRING_ONE);
        monthlyCardEditInfo.setPaymentChannel(JddConstant.StringNumber.STRING_ONE);
        log.info("新增操作记录信息:{}", monthlyCardEditInfo);
        return iMonthlyCardEditInfoService.save(monthlyCardEditInfo);
    }

    /**
     * 处理编辑时，在场车辆转卡
     * @param enterLogList
     * @param unUsePace
     * @param monthlyCardInfo
     * @param monthlyPackageInfo
     */
    @Override
    public void dealCarLog(List<ParkCarEnterLog> enterLogList,List<ParkSpace> unUsePace,
                              MonthlyCardInfo monthlyCardInfo,MonthlyPackageInfo monthlyPackageInfo){
        MonthlyCardInfoServiceImpl monthlyCardInfoService  = new MonthlyCardInfoServiceImpl();

        int count =0;
        List<ParkCarEnterLog> addParkCarEnterLogs = new ArrayList<>();
        List<MonthlyCarTypeConvert> monthlyCarTypeConverts = new ArrayList<>();
        for (ParkCarEnterLog parkCarEnterLog:enterLogList){
        	// 开过期月租，在场车辆的入场时间在月租结束时间之后，不处理
            if (monthlyCardInfo.getEndTime().before(DateUtil.fomatDateTime(parkCarEnterLog.getCarEnterTime()))){
                continue;
            }
            if(count>=unUsePace.size()){
                break;
            }
            if (StringUtils.isNotEmpty(parkCarEnterLog.getParkNumber())){
                continue;
            }
            // 查询未被绑定的车位信息
            QueryWrapper<ParkSpace> spaceQueryWrapper1 = new QueryWrapper<>();
            spaceQueryWrapper1.eq("park_code", monthlyCardInfo.getParkCode());
            spaceQueryWrapper1.eq("monthly_card_id", monthlyCardInfo.getId());
            spaceQueryWrapper1.eq("park_status", 0);
            spaceQueryWrapper1.eq("area_id",parkCarEnterLog.getAreaId());
            List<ParkSpace> spaceList = parkSpaceService.list(spaceQueryWrapper1);
            if (CollectionUtils.isEmpty(spaceList)){
                continue;
            }
            ParkSpace parkSpace = spaceList.get(0);
            parkSpace.setPlateNo(parkCarEnterLog.getPlateNo());
            parkSpace.setMonthlyCode(monthlyCardInfo.getMonthlyCode());
            parkSpace.setMonthlyCardId(monthlyCardInfo.getId());
            parkSpace.setParkStatus("1");
            parkSpaceService.updateById(parkSpace);
            parkCarEnterLog.setParkNumber(parkSpace.getParkNumber());
            count++;
            // 新增入场记录
            parkCarEnterLog.setId(SnowFlakeUtil.getId());
            parkCarEnterLog.setCarTypeId(monthlyPackageInfo.getMonthlyTypeId());
            parkCarEnterLog.setCarTypeName(monthlyPackageInfo.getMonthlyTypeName());
            parkCarEnterLog.setCarNature("1");
            parkCarEnterLog.setEnterType(JddConstant.IntNumber.INT_ZERO);
            parkCarEnterLog.setCreateTime(new Date());
            parkCarEnterLog.setMonthlyCardId(monthlyCardInfo.getId());
            // 若入场时间在月卡开始之后，新增转卡记录，否则，生成欲转卡记录
            if (DateUtil.fomatDateTime(parkCarEnterLog.getCarEnterTime()).after(monthlyCardInfo.getBeginTime())
                    && DateUtil.fomatDateTime(parkCarEnterLog.getCarEnterTime()).before(monthlyCardInfo.getEndTime())) {
                String time = DateUtil.addSecond(parkCarEnterLog.getCarEnterTime(), JddConstant.IntNumber.INT_ONE);
                parkCarEnterLog.setCarEnterTime(time);
                parkCarEnterLog.setIsTransfer(JddConstant.StringNumber.STRING_TWO);
            } else {
                parkCarEnterLog.setIsTransfer(JddConstant.StringNumber.STRING_ONE);
                parkCarEnterLog.setCarEnterTime(DateUtil.fomatDateTimeStr(monthlyCardInfo.getBeginTime()));
            }
            addParkCarEnterLogs.add(parkCarEnterLog);
            MonthlyCarTypeConvert monthlyCarTypeConvert = monthlyCardInfoService.getMonthlyCarTypeConvert(monthlyCardInfo, parkCarEnterLog, monthlyPackageInfo);
            monthlyCarTypeConverts.add(monthlyCarTypeConvert);
        }
        if(addParkCarEnterLogs.size() > 0){
        	iparkCarEnterLogService.saveBatch(addParkCarEnterLogs);
        	try {
        		for(ParkCarEnterLog parkCarEnterLog : addParkCarEnterLogs){
        			ParkCarEnterLogSyncV3Vo entity = new ParkCarEnterLogSyncV3Vo();
        			entity.setParkCarEnterLogStr(JSON.toJSONString(parkCarEnterLog));
        			// 月租车
        			if(StringUtils.isNotBlank(parkCarEnterLog.getParkNumber())){
        				entity.setParkStatus(JddConstant.ParkSpace.PARKSTATUS_ONE);
        				entity.setSourceAreaId(parkCarEnterLog.getAreaId());
        			}else{
        				// 临时车
        				entity.setParkStatus(JddConstant.ParkSpace.PARKSTATUS_ZERO);
        			}
                    String url = "";
        			sdkIdentifyResultPushLogV3Service.sendMessageV3(entity,url);
        		}
        	} catch (Exception e) {
        		e.printStackTrace();
        		log.info("新增月租车上传到云端失败->{}",e);
        	}
        }
        iMonthlyCarTypeConvertService.saveBatch(monthlyCarTypeConverts);
    }

    @Override
    public void dealCarLog(List<ParkCarEnterLog> enterLogList, List<ParkSpace> unUsePace, MonthlyCardInfo monthlyCardInfo, MonthlyPackageInfo monthlyPackageInfo, AddMonthlyCardInfoVO addMonthlyCardInfoVO) {
        MonthlyCardInfoServiceImpl monthlyCardInfoService  = new MonthlyCardInfoServiceImpl();

        int count =0;
        List<ParkCarEnterLog> addParkCarEnterLogs = new ArrayList<>();
        List<MonthlyCarTypeConvert> monthlyCarTypeConverts = new ArrayList<>();
        List <ParkSpace> parkSpaces = new ArrayList<>();
        for (ParkCarEnterLog parkCarEnterLog:enterLogList){
            // 开过期月租，在场车辆的入场时间在月租结束时间之后，不处理
            if (monthlyCardInfo.getEndTime().before(DateUtil.fomatDateTime(parkCarEnterLog.getCarEnterTime()))){
                continue;
            }
            if(count>=unUsePace.size()){
                break;
            }
            if (StringUtils.isNotEmpty(parkCarEnterLog.getParkNumber())){
                continue;
            }
            // 查询未被绑定的车位信息
            QueryWrapper<ParkSpace> spaceQueryWrapper1 = new QueryWrapper<>();
            spaceQueryWrapper1.eq("park_code", monthlyCardInfo.getParkCode());
            spaceQueryWrapper1.eq("monthly_card_id", monthlyCardInfo.getId());
            spaceQueryWrapper1.eq("park_status", 0);
            spaceQueryWrapper1.eq("area_id",parkCarEnterLog.getAreaId());
            List<ParkSpace> spaceList = parkSpaceService.list(spaceQueryWrapper1);
            if (CollectionUtils.isEmpty(spaceList)){
                continue;
            }
            ParkSpace parkSpace = spaceList.get(0);
            parkSpace.setPlateNo(parkCarEnterLog.getPlateNo());
            parkSpace.setMonthlyCode(monthlyCardInfo.getMonthlyCode());
            parkSpace.setMonthlyCardId(monthlyCardInfo.getId());
            parkSpace.setParkStatus("1");
            parkSpaceService.updateById(parkSpace);
            parkSpaces.add(parkSpace);
            parkCarEnterLog.setParkNumber(parkSpace.getParkNumber());
            count++;
            // 新增入场记录
            parkCarEnterLog.setId(SnowFlakeUtil.getId());
            parkCarEnterLog.setCarTypeId(monthlyPackageInfo.getMonthlyTypeId());
            parkCarEnterLog.setCarTypeName(monthlyPackageInfo.getMonthlyTypeName());
            parkCarEnterLog.setCarNature("1");
            parkCarEnterLog.setEnterType(JddConstant.IntNumber.INT_ZERO);
            parkCarEnterLog.setCreateTime(new Date());
            parkCarEnterLog.setMonthlyCardId(monthlyCardInfo.getId());
            // 若入场时间在月卡开始之后，新增转卡记录，否则，生成欲转卡记录
            if (DateUtil.fomatDateTime(parkCarEnterLog.getCarEnterTime()).after(monthlyCardInfo.getBeginTime())
                    && DateUtil.fomatDateTime(parkCarEnterLog.getCarEnterTime()).before(monthlyCardInfo.getEndTime())) {
                String time = DateUtil.addSecond(parkCarEnterLog.getCarEnterTime(), JddConstant.IntNumber.INT_ONE);
                parkCarEnterLog.setCarEnterTime(time);
                parkCarEnterLog.setIsTransfer(JddConstant.StringNumber.STRING_TWO);
            } else {
                parkCarEnterLog.setIsTransfer(JddConstant.StringNumber.STRING_ONE);
                parkCarEnterLog.setCarEnterTime(DateUtil.fomatDateTimeStr(monthlyCardInfo.getBeginTime()));
            }
            addParkCarEnterLogs.add(parkCarEnterLog);
            MonthlyCarTypeConvert monthlyCarTypeConvert = monthlyCardInfoService.getMonthlyCarTypeConvert(monthlyCardInfo, parkCarEnterLog, monthlyPackageInfo);
            monthlyCarTypeConverts.add(monthlyCarTypeConvert);
        }
        addMonthlyCardInfoVO.setUpdateParkSpace(parkSpaces);
        addMonthlyCardInfoVO.setAddParkCarEnterLogs(addParkCarEnterLogs);
        addMonthlyCardInfoVO.setMonthlyCarTypeConverts(monthlyCarTypeConverts);
        if(addParkCarEnterLogs.size() > 0){
        	iparkCarEnterLogService.saveBatch(addParkCarEnterLogs);
        }
        iMonthlyCarTypeConvertService.saveBatch(monthlyCarTypeConverts);
    }

}
